/*******************************************************************************
 * Name: Stephen Durfey
 * Class: CS335
 * Time: Tue, Thurs 1:00-2:15pm
 * Professor: Dr. Michael Poor
 * Description: This program creates objects that contain a word. Once an object
 *              is created, it is checked to see if it is a palindrome. If it is
 *              then it will be printed to the screen. Else nothing will happen
 *              and the program will read the next word from the file.
 *******************************************************************************/


#include <iostream>
#include <fstream>
#include <cstring>
using namespace std;

const int LINE_BUFFER_SIZE = 256;

struct CharLinkD {

CharLinkD *prev;
char c;
CharLinkD *next;

};

// detects if a word is a palindrome
void makeList(const char candidate[], CharLinkD* &head, CharLinkD* &tail) {

	// get the length of the c-string
	int len = strlen(candidate);


	CharLinkD* first = NULL;
	CharLinkD* temp = NULL;

	//make first link
	first = new CharLinkD;
	first->prev = NULL;
	first->next = NULL;
	first->c = candidate[0];

	//make head and tail point to it
	head = first;
	tail = first;

	//make the list

	for(int i = 1; i < len; i++)
	{
		//make a new link for each character left
		temp = new CharLinkD;

		//make a link that goes back to tail
		temp->prev = tail;

		//link forward is null
		temp->next=NULL;

		temp->c = candidate[i];

		//set up link backward to end of list
		tail->next = temp;

		//new tail is now last element
		tail = temp;
	}
}

bool isPalindrome(CharLinkD * head, CharLinkD * tail) {
	bool answer = false;

        CharLinkD* begin;
        CharLinkD* end;
        
        begin = head;  //assigns begin to the first character in the string
        end = tail;    //assigns end to the last character in the string
        
        //continues while begin is pointing to something
        //and being->c and end->c are equal. if(begin->c == end->c) is false
        //then we do not have a palindrome. However, if that is true for the entire
        //word, then begin will eventually point to NULL, which would indicate
        //that the loop found a palindrome
        while(begin && begin->c == end->c)
        {
            begin = begin->next; //moves begin to the next character in the string
            end = end->prev; //moves end to the previous character in the string
        }
        
        //this only evaluates true if begin is pointing to NULL. if it is
        //the while loop discovered a palindrome. 
        if(!begin)
            answer = true;
        
        return answer;
}

// reads in the list of words
// prints out word if it is a palendrome
int main() {

	CharLinkD *head = NULL;
	CharLinkD *tail = NULL;

	// open a file for READING
	ifstream infile("words");

	// create a buffer to hold a line of text from the file
	char line[LINE_BUFFER_SIZE];

	// while not at the end of file
	while (!infile.eof()) {
		// get a line of the file into the buffer
		infile.getline(line, LINE_BUFFER_SIZE);


		makeList(line, head, tail);
		// use our function to check if it's a palindrome
		if (isPalindrome(head, tail)) {
			cout << line << endl;
		}
	}
	infile.close();
}
